package ase.eleitweg.server;

import java.rmi.RemoteException;
import java.rmi.server.UnicastRemoteObject;
import java.util.*;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.xml.XmlBeanFactory;
import org.springframework.core.io.ClassPathResource;

import com.google.inject.Inject;

import ase.eleitweg.common.*;
import ase.eleitweg.server.db.DatabaseFactory;
import ase.eleitweg.server.db.ELeitwegDAO;

public class WorkflowController implements WorkflowManager {
	
	private static WorkflowController instance = null;
	
	private static WorkflowManager remoteInstance = null;
	
	private List<Workflow> cache = null;
	
	@Inject ELeitwegDAO dao;
	private WorkflowController() {
		//initDAO();
	}
	
	private static Logger log = Logger.getLogger(WorkflowController.class);

	//private ELeitwegDAO dao;

	/**
	 * Initiate the DB-Interface
	 */
	/*private void initDAO() {
		log.info("Initalizing DAO");
		dao = DatabaseFactory.getDB();

	}*/
	
	public static WorkflowController getInstance() {
		if(instance == null) {
			instance = new WorkflowController();
		}
		return instance;
	}
	
	public static WorkflowManager getRemoteInstance() throws RemoteException {
		if(instance == null) {
			instance = new WorkflowController();
		}
		if(remoteInstance == null) {
			remoteInstance = (WorkflowManager) UnicastRemoteObject.exportObject((WorkflowManager) instance, 0);
		}
		return remoteInstance;
	}
	
	public int addWorkflow(Workflow w) {
		for(Workflow wx : getWorkflows()) {
			if(wx.getName().equals(w.getName())) {
				return -1;
			}
		}
		cache = null;
		return dao.createWorkflow(w);
		
	}
		
	public List<Workflow> getWorkflows() {
		if(cache == null) {
			cache = dao.getAllWorkflows();
			
		} 
		return new Vector<Workflow>(cache);
	}
	
	public void deleteWorkflow(Workflow w) {
		for(Run r : dao.getInstances(w.getWNr())) {
			dao.deleteInstance(r);
		}
		dao.deleteWorkflow(w);
		cache = null;
	}
	
	public Workflow copyWorkflow(Workflow w) {
		Workflow clone = w.clone();
		//create different name (collision-free!)
		List<Workflow> wfs = getWorkflows();
		boolean duplicate = false;
		int suffix = 2;
		while(true) {
			duplicate = false;
			for(Workflow wy : wfs) {
				if(wy.getName().equals(clone.getName() + Integer.toString(suffix))) {
					duplicate = true;
				}
			}
			if(!duplicate) {
				clone.setName(clone.getName() + Integer.toString(suffix));
				break;
			} else {
				suffix++;
			}
		}
		int id = addWorkflow(clone);
		for(Workflow wx : getWorkflows()) {
			if(wx.getWNr() == id) {
				return wx;
			}
		}
		return null;
	}
	
	public void updateWorkflow(Workflow w) {
		dao.updateWorkflow(w);
		cache = null;
	}
	
	public synchronized Workflow getWorkflow(int id) {
		if(cache != null) {
			for(Workflow w : cache) {
				if(w.getWNr() == id) { 
					return w;
				}
			}
		} else {
			return dao.getWorkflow(id);
		}
		return null;
	}

}
